package com.caipiao.lottery.status;

/**
 * @author GaoFeng
 * 
 */

import static org.jboss.netty.channel.Channels.pipeline;
import static org.jboss.netty.handler.codec.http.HttpHeaders.setContentLength;
import static org.jboss.netty.handler.codec.http.HttpHeaders.Names.CONTENT_TYPE;
import static org.jboss.netty.handler.codec.http.HttpResponseStatus.FORBIDDEN;
import static org.jboss.netty.handler.codec.http.HttpResponseStatus.OK;
import static org.jboss.netty.handler.codec.http.HttpVersion.HTTP_1_1;

import java.net.InetSocketAddress;   
import java.net.UnknownHostException;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

import org.jboss.netty.bootstrap.ServerBootstrap;
import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBuffers;
import org.jboss.netty.channel.ChannelFuture;
import org.jboss.netty.channel.ChannelFutureListener;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.channel.ChannelPipeline;
import org.jboss.netty.channel.ChannelPipelineFactory;
import org.jboss.netty.channel.MessageEvent;
import org.jboss.netty.channel.SimpleChannelUpstreamHandler;
import org.jboss.netty.channel.socket.oio.OioServerSocketChannelFactory;
import org.jboss.netty.handler.codec.http.DefaultHttpResponse;
import org.jboss.netty.handler.codec.http.HttpChunkAggregator;
import org.jboss.netty.handler.codec.http.HttpRequest;
import org.jboss.netty.handler.codec.http.HttpRequestDecoder;
import org.jboss.netty.handler.codec.http.HttpResponse;
import org.jboss.netty.handler.codec.http.HttpResponseEncoder;
import org.jboss.netty.util.CharsetUtil;

import com.caipiao.lottery.core.SYSInterface;
import com.caipiao.lottery.log.TraceLogger;
import com.caipiao.lottery.lty.server.LtyMsgHandler;
import com.caipiao.util.db.DBHelper;

//主监听服务
public class StatusHttpServer
{
	private int m_port;
	
	public StatusHttpServer(int port)
	{
		this.m_port = port;
	}
	
	ServerBootstrap bootstrap = null;
	
	public void startServer() throws UnknownHostException
	{
		Executor srvThrdPool = Executors.newCachedThreadPool();
		
			bootstrap = new ServerBootstrap(
	                new OioServerSocketChannelFactory(
	                		srvThrdPool,
	                		srvThrdPool));

		bootstrap.setPipelineFactory(new StatusHttpServerPipelineFactory());
		
		bootstrap.bind(new InetSocketAddress(this.m_port));
		
		String ip = "localhost";
		
		String url = "http://" + ip + ":" + String.valueOf(this.m_port) + "/status";
		TraceLogger.System.debug("StatusHttpServer访问地址:  " + url + "  查询系统状态");
	}
	
	class StatusHttpServerPipelineFactory implements ChannelPipelineFactory
	{
	    public ChannelPipeline getPipeline() throws Exception 
	    {
	        ChannelPipeline pipeline = pipeline();
	        pipeline.addLast("decoder", new HttpRequestDecoder());
	        pipeline.addLast("aggregator", new HttpChunkAggregator(102400));	//100k数据
	        pipeline.addLast("encoder", new HttpResponseEncoder());
	        pipeline.addLast("handler", new StatusHttpServerHandler()); 
	        return pipeline;
	    }
	}
}

//HTTP处理句柄
class StatusHttpServerHandler extends SimpleChannelUpstreamHandler 
{
	public StatusHttpServerHandler()
	{
	}
	
	private String getStatusHandleString()
	{
		StringBuffer str_buff = new StringBuffer();

		str_buff.append("<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n");
        str_buff.append("<status>\r\n");
        
        //数据库状态
        str_buff.append(DBHelper.Instance().Get_DB_Status());
  
        if (SYSInterface.Instance().model_ltysrv)
        {
        	str_buff.append("<ltyserver>\r\n");
        	str_buff.append("已完成:" + LtyMsgHandler.Get_Req_Over_Count() + " - 处理中:" + LtyMsgHandler.Get_Req_Count() + "\r\n");
        	str_buff.append("</ltyserver>\r\n");

			/*
        	str_buff.append("<sessioncache>\r\n");
        	str_buff.append("size:" + SessionManager.Instance().GetCacheSize());
        	str_buff.append("</sessioncache>\r\n");
        	*/
        }
        
        str_buff.append("</status>\r\n");
        
		return str_buff.toString();
	}
    
    @Override
    public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception 
    {
        Object msg = e.getMessage();
        if (msg instanceof HttpRequest) 
        {
        	HttpRequest req = (HttpRequest) msg;
        	String req_uri = req.getUri();
        	
        	//状态
        	if (req_uri.startsWith("/status"))
        	{
        		String statusStr = this.getStatusHandleString();
        		ChannelBuffer resp_buff =  ChannelBuffers.copiedBuffer(statusStr, CharsetUtil.UTF_8);
                
    			HttpResponse resp = new DefaultHttpResponse(HTTP_1_1, OK);
    			resp.headers().set(CONTENT_TYPE, "text/html; charset=UTF-8");
    			resp.setContent(resp_buff);
    			setContentLength(resp, resp_buff.readableBytes());
    			ChannelFuture cf = ctx.getChannel().write(resp);
    			
    			cf.addListener(ChannelFutureListener.CLOSE);		//总是断开连接
    			return;
        	}
        	
        	//清空缓存
        	if (req_uri.startsWith("/resetdb"))
        	{
        		DBHelper.Instance().Reset();
        			
    			ChannelBuffer resp_buff =  ChannelBuffers.copiedBuffer("Reset DB Pool OK", CharsetUtil.UTF_8);
                
    			HttpResponse resp = new DefaultHttpResponse(HTTP_1_1, OK);
    			resp.headers().set(CONTENT_TYPE, "text/html; charset=UTF-8");
    			resp.setContent(resp_buff);
    			setContentLength(resp, resp_buff.readableBytes());
    			ChannelFuture cf = ctx.getChannel().write(resp);
    			
    			cf.addListener(ChannelFutureListener.CLOSE);		//总是断开连接
    			return;
        	}

        	//非指定上下文地址访问
        	HttpResponse resp = new DefaultHttpResponse(HTTP_1_1, FORBIDDEN);
            ChannelFuture cf = ctx.getChannel().write(resp);
            cf.addListener(ChannelFutureListener.CLOSE);		//总是断开连接
        }
    }
}


